import { Message, MessageBox } from '@yundi-fe/sec-ui'
import store from '@/store'
import router from '@/router'
import { debounce } from 'lodash'
/**
 * @description 状态码
 * 网关：200: OK, 201: Created, 401: Unauthorized, 403:	Forbidden, 404:	Not Found
 * 数据：0: SUCCESS；1: FAIL，reponse: data : {"code":0,"msg":null,"data":{}}
 */

const defaultResponse = { status: 200, data: { code: 0, data: [] } }
export const statusMap = new Map([
  [200, { flg: 'ok', msg: 'OK' }],
  [201, { flg: 'ok', msg: 'Created' }],
  [401, { flg: 'fail', msg: 'Unauthorized' }],
  [403, { flg: 'fail', msg: 'Forbidden' }],
  [404, { flg: 'fail', msg: 'Not Found' }],
  [500, { flg: 'fail', msg: 'Not Found' }],
  [503, { flg: 'fail', msg: 'Service Unavailable' }]
])

export const codeMap = new Map([
  [200, { flg: 'success', msg: 'data success' }],
  [5001, { flg: 'success', msg: 'will update password' }],
  [1, { flg: 'fail', msg: 'data response fail [ data.code is not 0 ]' }],
  [
    500,
    {
      flg: 'fail',
      key: 'captcha_expired',
      msg: 'data response fail [ 验证码无效 ]'
    }
  ],
  [
    'C010001',
    {
      flg: 'fail',
      key: 'send_msg_error',
      msg: 'data response fail [ 发送验证码失败 ]'
    }
  ],
  [
    'C100002',
    {
      flg: 'fail',
      key: 'captcha_expired',
      msg: 'data response fail [ 请刷新验证码 ]'
    }
  ],
  [
    'C100003',
    {
      flg: 'fail',
      key: 'captcha_expired',
      msg: 'data response fail [ 请刷新验证码 ]'
    }
  ],
  [
    'C100014',
    {
      flg: 'fail',
      key: 'captcha_error',
      msg: 'data response fail [ 验证码错误 ]'
    }
  ],
  [
    'C100010',
    {
      flg: 'fail',
      key: 'no_captcha',
      msg: 'data response fail [ 请输入图形验证码 ]'
    }
  ],
  [
    'C100005',
    {
      flg: 'fail',
      key: 'usrOrPswError',
      msg: 'data response fail [ 用户名或者密码错误 ]'
    }
  ],
  [
    'A010001',
    {
      flg: 'fail',
      key: 'InvalidToken',
      msg: 'data response fail [ token 过期 ]'
    }
  ],
  ['C010004', { flg: 'fail', key: 'password_rule', msg: '密码规则不符合要求' }],
  [
    'C010006',
    { flg: 'fail', key: 'password_expire', msg: '密码已经重置，请联系管理员' }
  ],
  [
    'C100020',
    {
      flg: 'fail',
      key: 'to_much_error_count',
      msg: '由于您登入时密码错误次数过多, 请5分钟后重新登录'
    }
  ],
  [
    'C100021',
    {
      flg: 'fail',
      key: 'to_much_error_count',
      msg: '您的账号已被禁止登入, 请5分钟后再试。'
    }
  ],
  ['C010007', { flg: 'fail', key: 'repeat_user', msg: '当前用户已经存在' }]
])
const alertMessage = debounce(function (msg) {
  Message({
    message: msg,
    type: 'error',
    duration: 5 * 1000
  })
}, 500)
// 对于该列表中的错误信息会在页面弹出提示信息
const alertMsg = [
  'captcha_expired',
  'password_expire',
  'repeat_user',
  'usrOrPswError',
  'no_captcha',
  'captcha_error',
  'to_much_error_count'
]

/**
 * @description 网关状态码
 * @param {*} response
 */
const gateway = (response = defaultResponse) => {
  const PseudoNumber = response.status - 0

  // 尝试将code强制转为number
  const iCode = !isNaN(PseudoNumber) ? PseudoNumber : response.status

  const meta = statusMap.get(iCode)

  return [meta.flg === 'ok' ? null : meta, response]
}

/**
 *
 * @param {*} response
 */
const dataGatway = (response = defaultResponse) => {
  if (!response.data) {
    return [null, response]
  }

  const PseudoNumber = response.data.code - 0

  // 尝试将code强制转为number
  const iCode = !isNaN(PseudoNumber) ? PseudoNumber : response.data.code

  const meta = codeMap.get(iCode)

  return [meta.flg === 'success' ? null : meta, response]
}

/**
 * @description 判断当前是否在登录页面
 * @returns boolean
 */
const inLogin = () => {
  const currentHash = decodeURIComponent(location.hash).split('#')[1]

  const aUrl = currentHash ? currentHash.split('?') : []

  return aUrl.includes('/login')
}
logError.isFirst = true
export function logError(error, response) {
  console.error(`fetch data response has Error: ${JSON.stringify(error)},
   Response: ${JSON.stringify(response)}`)
  if (error.key === 'InvalidToken') {
    if (!logError.isFirst) return
    logError.isFirst = false
    console.log('token 无效-------------')
    if (inLogin()) return
    MessageBox.alert('Token 已经过期,请重新登录!', '提示', {
      confirmButtonText: '确定',
      callback: (action) => {
        store.dispatch('user/resetToken').then(() => {
          logError.isFirst = true
          if (inLogin()) return
          // 跳转登录
          const toPath = location.hash.split('#')[1]
          router.replace({ path: `/login?redirect=${toPath}` })
        })
      }
    })
  } else {
    if (alertMsg.includes(error.key)) {
      const msg = response.data
        ? response.data.message || response.data.msg
        : error
      alertMessage(msg)
    } else {
      const msg = '网络异常，请稍后重试'
      alertMessage(msg)
    }
  }
  return response['data']
}

export const status = (response = {}) => {
  try {
    // 判断外部网关状态码
    const [error, res] = gateway(response)
    if (error) {
      logError(error, res)
      return res['data']
    }

    // 判断数据网关状态码
    const [codeError, codeRes] = dataGatway(response)

    if (codeError) {
      logError(codeError, codeRes)
      throw new Error()
    }

    return response['data']?.['body']
  } catch (e) {
    console.error(`[ suatus error ]: ${e}`)
    return Promise.reject(response['data'])
  }
}
